home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / SPAWNO41.ARJ / SPAWNO.DOC < prev    next >
Text File  |  1992-04-26  |  21KB  |  464 lines

  1. SPAWNO v4.10    4/26/91    disk/EMS/XMS/INT15 swapping replacement for spawn()
  2. (c) Copyright 1990,1991,1992 Ralf Brown.  All Rights Reserved.
  3.  
  4.  
  5. -----------------
  6. LICENSE
  7.  
  8. This document and the associated header file, libraries, and source and
  9. object modules may be freely copied provided that:
  10.      1) all of the files are copied as a group (such as in a single
  11.     archive).  See below for a list of files.
  12.      2) the files are not modified in any way (including removal or
  13.     alteration of copyright notices or this license)
  14.      3) no charge beyond a cost-recovery fee not to exceed $5, or a
  15.     general telecommunications connection fee, is made
  16.  
  17. The source and/or object code comprising the public SPAWNO distribution
  18. may be incorporated at no charge into programs which are distributed or
  19. sold to others provided that:
  20.      1) credit is given in the documentation.  A mention such as
  21.        "This product uses the SPAWNO routines by Ralf Brown
  22.         to minimize memory use while shelling to DOS and
  23.         running other programs."
  24.     is sufficient.
  25.      2) you drop me a line telling me that you are using SPAWNO and
  26.     in which product(s) you are using it (see addresses at the
  27.     end of this file).  I'm interested in finding out how wide-
  28.     spread the use of SPAWNO becomes.
  29.  
  30.  
  31. -----------------
  32. DISCLAIMER
  33.  
  34. Although both I and others have tested the code which comprises SPAWNO,
  35. it is entirely possible that SPAWNO may malfunction in environments or
  36. under circumstances in which it has not been tested.  This code is
  37. provided AS IS, and the author disclaims any and all responsibility for
  38. damages (both consequential and incidental) resulting from the use or
  39. misuse of SPAWNO.  Sole responsibility for determining the suitability
  40. of the code rests with the user.
  41.  
  42.  
  43. -----------------
  44. FILES
  45.  
  46. The disk or archive you received should contain the following files:
  47.  
  48.     SPAWNO.DOC    this file
  49.     SPAWNO.H    the header file providing prototypes for the functions
  50.     SPAWNx.LIB    versions of the library for each of [T]iny, [S]mall,
  51.             [C]ompact, [M]edium, [L]arge, and [H]uge memory
  52.             models.
  53.     SPAWNTP.OBJ    Turbo Pascal version of SPAWNO
  54.     SPAWNO.PAS    Turbo Pascal unit encapsulating SPAWNO
  55.     SPAWN_MS.ZIP    Microsoft C versions of compiler-specific functions
  56.     MSC.BAT        replace Turbo C specific functions in libraries with
  57.             Microsoft C versions.
  58.     NOREPLAC.BAT    remove replacements for the standard spawn..()
  59.             functions from the libraries.
  60.     SWAPTEST.C    example program for testing
  61.     TEST.PAS    example program for testing
  62.     SOURCE.ZIP    archive containing partial source code for SPAWNO
  63.         _SPAWNO.H        header file for recompiling library
  64.         *.C            source for the spawn..() and spawn...o() functions
  65.         RULES.ASI        shortened and modified Turbo C macro file
  66.         SPAWNO.INC        include file for various important constants
  67.         SPAWNPTH.ASM    source for the path search
  68.         CHECKEXT.ASM    check for 'file', 'file.EXE', and 'file.COM'
  69.         SWAP_EMS.ASM    support routines for swapping to EMS
  70.         SWAPLIST.ASM    specify which swap types will be linked in
  71.         SPAWNENV.ASM    make an environment block from an array of strings     
  72.         SPAWNERR.ASM    set _doserrno and errno
  73.         MAKEFILE
  74.  
  75.  
  76. -----------------
  77. WHAT'S NEW
  78.  
  79. Changes/fixes since version 4.00:
  80.     Now swaps to disk with non-NULL swap list in large-data memory models
  81.     Now correctly deletes swap file if child program changes directories
  82.     If the given program name is "FOO", and both "FOO" and either
  83.        "FOO.COM" and/or "FOO.EXE" exist in the same directory, it will
  84.        now execute either "FOO.COM" or "FOO.EXE" rather than "FOO", as
  85.        both version 4.00 and the Borland library functions do.  To
  86.        execute "FOO", pass "FOO." rather than just "FOO" to the function.
  87.     Fixed bug which may have led to a partially corrupted environment
  88.        in a few circumstances
  89.  
  90.  
  91. -----------------
  92. INSTALLATION
  93.  
  94. If you are using Turbo C, Turbo C++, or Borland C++, simply dearchive
  95. the libraries and header file and place them where your compiler can
  96. find them.  If you are using Microsoft C, dearchive SPAWN_MS.ZIP and
  97. then run the MSC batch file to replace the compiler-specific functions
  98. in the libraries with Microsoft C versions.  Please do not run this
  99. batch file on your original copy of the libraries.
  100.  
  101. If you are using Turbo Pascal, unarchive SPAWNTP.OBJ and SPAWNO.PAS.
  102. Compile SPAWNO.PAS and then add a USES SPAWNO; line to your program.
  103. After that you can call the function SPAWN() as desired.  The
  104. distribution does not contain a pre-compiled version because .TPU
  105. files are not compatible between different versions of Turbo Pascal.
  106.  
  107.  
  108. -----------------
  109. INSTRUCTIONS
  110.  
  111. As distributed, SPAWNO contains replacements for the standard spawn..()
  112. functions.  You can use SPAWNO with absolutely no changes to your
  113. existing source code; however, you will probably want to call
  114. init_SPAWNO() from main(), and include SPAWNO.H for that source file.
  115. The initialization function takes two arguments: the first is a string
  116. containing a list of directories (separated by semicolons) in which to
  117. attempt to store the swap file when swapping to disk. The second
  118. specifies which swap devices to attempt to use; it may be either
  119. SWAP_ANY or the ORing or addition of any combination of SWAP_DISK,
  120. SWAP_EMS, SWAP_EXT, and SWAP_XMS (such as SWAP_DISK|SWAP_XMS).    If you
  121. do not call init_SPAWNO(), the defaults are to attempt all swap devices
  122. and to store the swap file in the current directory when swapping to
  123. disk.  init_SPAWNO() will set the swap file directory list to the first
  124. of the following to have a non-NULL, non-empty value: the environment
  125. variable SWAPDIR, the passed parameter, the environment variable TEMP,
  126. and the environment variable TMP.  Note that init_SPAWNO is the only
  127. function in the library which uses these environment variables.
  128.  
  129. After making the above change, recompile your existing code, but include
  130. the SPAWNO library in the link step.  Note that SPAWNO does not support
  131. the P_OVERLAY spawn type--any calls using that argument should be
  132. replaced with the corresponding exec..() function.  If a SPAWNO function
  133. is called with P_OVERLAY, it simply returns an error.
  134.  
  135. For backwards compatibility with previous versions of SPAWNO, and for
  136. those who (for whatever reason) require the use of both the swapping and
  137. standard spawn..() functions, there is a second set of functions which
  138. take an explicit swap directory argument.  To use them, include the
  139. header file SPAWNO.H.  Then use the functions provided in this
  140. archive--spawnvo(), spawnlo(), spawnvpo(), etc--as you would the
  141. corresponding spawnv(), spawnl(), etc, except replace the first argument
  142. by a string containing the path where the swap file is to be stored.
  143. Note that the swap file path is required even when swapping to XMS, EMS,
  144. or plain extended memory, as SPAWNO will swap to disk anyway if there is
  145. not enough memory available.
  146.  
  147. If you require the use of both the swapping and standard spawn..()
  148. functions, you will need to run the NOREPLAC.BAT batch file to remove
  149. the modules containing the replacements for the standard functions or
  150. arrange the linker command line such that SPAWNx.LIB is listed after the
  151. standard runtime library (for Turbo/Borland C users, the latter requires
  152. a separate TLINK command, as TCC/BCC places any libraries specified on
  153. the command line prior to the runtime library).     Please do not run
  154. NOREPLAC on your original copy of the libraries, as the process is
  155. destructive and cannot be reversed.
  156.  
  157. The spawn?p??() functions search for both .COM and .EXE files in the
  158. current directory and then in the pathed directories if no extension is
  159. given, but use the specified extension if present.  If a full pathname
  160. is given to those functions, only the specified directory is searched.
  161. If both a path and an extension are given, only that specific file will
  162. be loaded.  The other spawn..() functions check the current directory
  163. only.  For all functions, if the specified filename does not contain an
  164. extension, SPAWNO will try the exact name given and the name with .COM
  165. and .EXE extensions. The extension-less name will be used if neither
  166. .COM nor .EXE exist.  To force the use of the extensionless file even
  167. if a .COM or .EXE with the same name exists in the same directory,
  168. append a period, i.e. use "PROGRAM." rather than just "PROGRAM" as
  169. the name.
  170.  
  171. When linking, you must include SPAWNx.LIB.  A sample TCC line would be
  172.  
  173.     tcc -mc <other-flags> sample spawnc.lib library.lib
  174.  
  175. This results in 208 to 288 bytes remaining in memory (depending on swap
  176. type) while the spawned program executes.  However, if you want to keep
  177. an interrupt hooked which might be invoked while spawned, you must set
  178. __spawn_resident large enough that *all* code and data which could be
  179. invoked by that interrupt is kept resident[1].    SPAWNO automatically
  180. deactivates INT 23h and INT 24h and restores them before returning to
  181. the caller unless __spawn_keepints is set to 1, so no extra work is
  182. required if those two are the only interrupts hooked by the program.
  183.  
  184. ----
  185. [1] Due to the segment layout used by C compilers, this option is probably
  186.     useful only when calling SPAWNO from assembly-language code (which can
  187.     localize such code and data near the start of the executable) or a
  188.     small program which uses a large amount of space in the far heap.
  189.  
  190.  
  191. -----------------
  192. ERROR MESSAGES
  193.  
  194. SPAWNO: stack too small, retrying
  195.     SPAWNO did not correctly determine the stack requirements for
  196.     the system on which it is running, but was able to determine
  197.     that the specified minimum size is insufficient.  On the retry,
  198.     the stack size is increased by one paragraph.  Since SPAWNO
  199.     cannot always detect the problem, which would result in
  200.     memory chain corruption, you should increase the value of
  201.     __spawn_res_stack to prevent a recurrence of this error
  202.     message.  For most systems, the default value of 4 paragraphs
  203.     will be sufficient.
  204.  
  205. SWAP ERR
  206.     The resident stub detected an error while trying to reload the
  207.     main portion of the program and aborted.  This may be due to
  208.     loading a TSR while swapped out or deleting the swap file.
  209.  
  210. SPAWNO: error reloading program, aborting
  211.     The main portion of SPAWNO detected an error while attempting
  212.     to restore the remainder of the program to memory.
  213.  
  214.  
  215. -----------------
  216. LIMITATIONS
  217.  
  218. After freeing all memory owned by the program except the initial (PSP)
  219. memory block and the environment, at least 384 bytes of conventional
  220. memory must be available.  SPAWNO uses this for its temporary stack.
  221. This is of particular importance for the Turbo Pascal variant, because
  222. setting the maximum heap size to the available memory or greater will
  223. use up all RAM and prevent SPAWNO from allocating its temporary stack
  224. unless memory is fragmented or there is DOS 5 high memory available.
  225.  
  226. SPAWNO may report insufficient memory even though the program to be
  227. executed would fit with up to 600 bytes to spare, due to the fact that
  228. part of the stack and all of the data used by DOS to start the program
  229. may be overwritten after the child program starts executing.
  230.  
  231. Functions which pass an explicit environment attempt to allocate enough
  232. memory to build the environment block which is passed to the DOS EXEC
  233. function.  If neither malloc() nor a DOS memory allocation request are
  234. successful, SPAWNO passes the original environment rather than the
  235. specified environment.
  236.  
  237. As distributed, SPAWNO functions which do not take an explicit
  238. environment pointer pass the calling program's original environment to
  239. the child, rather than the current environment as modified by putenv().
  240. You may recompile SPAWNO to pass the current environment (see
  241. _SPAWNO.H); if you do so, the caveat discussed in the previous paragraph
  242. will apply to all of the spawn..() functions.
  243.  
  244.  
  245. -----------------
  246. SUPPORT
  247.  
  248. Since I am not getting any money, I can't promise any support.    Those
  249. who have purchased the complete source code will receive priority over
  250. those who haven't, but even they will only receive support to the
  251. extent that I have spare time....
  252.  
  253.  
  254. -----------------
  255. ACKNOWLEDGEMENTS
  256.  
  257. Thanks to Gene McManus for testing the Microsoft versions of SPAWNO 3.0
  258. and 4.0.
  259.  
  260.  
  261. -----------------
  262. FUTURE PLANS
  263.  
  264. The next release will drop support for DOS 2.x (which is now over
  265. seven years old) to reduce the code size and further reduce the size
  266. of the resident stub.
  267.  
  268.  
  269. -----------------
  270. SPAWNO versus THE COMPETITION
  271.  
  272. Product:        SPAWNO        XSPAWN        SWAP
  273. Version:         4.02         1.34         1.0
  274. Author:             Ralf Brown      Whitney Software  Marty Del Vecchio
  275. Memory models:        tsmclh        tsmclh         tsm
  276. Supported DOS vers:    2.0-5.0           2.1-5.0          3.0-5.0
  277. Code size [1]:           4.2-5.6K           4.4-9K         1.5K
  278. Resident stub (bytes): 208-288          1277+2*env     1.8K+env [2]
  279. Direct replacement for
  280.     spawn..():         yes         yes          no
  281. Use in existing code
  282.     without changes:     yes          no          no
  283. Swap to disk:         yes         yes         yes
  284. Swap to EMS:         yes         yes         yes
  285. Swap to XMS:         yes          no          no
  286. Swap to INT 15h ext:     yes          no          no
  287. Multiple swap dirs:     yes         yes          no
  288. Automatic unique swap
  289.     file naming:     yes         yes          no
  290. May leave interrupts
  291.     hooked [3]:         yes          no         yes
  292. Swaps DOS5 high memory:     yes           ?           ?
  293. Free for any use:     yes         yes         yes
  294. Source included:       partial [4]     yes         yes
  295.  
  296. Notes:
  297. [1] For both SPAWNO and XSPAWN, the amount added to the executable's
  298.     size depends on which functions of the library are called and which
  299.     of the additional C runtime library function that are called by
  300.     SPAWNO/XSPAWN would have been included anyway.  SPAWNO's size may
  301.     be reduced by removing one or more swap types; the savings are
  302.     about 400 bytes per swap type (without EMS and non-XMS (INT 15h)
  303.     swapping, SPAWNO would add as little as 3.4K to the executable).
  304.  
  305. [2] SWAP's resident size depends on the location of the object code
  306.     within the executable.  The size reported here is the resident
  307.     size when SWAP immediately follows the Turbo C 2.0 startup code.
  308.  
  309. [3] For SPAWNO, enough of the program must be left in memory to keep all
  310.     interrupt handlers resident.  XSPAWN has no provision for keeping
  311.     an interrupt handler resident unless swapping is disabled; it does
  312.     however permit selection whether a given interrupt handler will
  313.     automatically be restored to its original value or pointed at an
  314.     IRET instruction while swapped out.     For SWAP, the swapper module
  315.     must be linked in after all code and data which might be accessed
  316.     by the interrupt handler(s).
  317.  
  318. [4] Full SPAWNO source code is available for purchase.    See ORDER.FRM for
  319.     details.
  320.  
  321.  
  322. -----------------
  323. Functions:
  324.     void init_SPAWNO(const char *swap_directories, int swap_types) ;
  325.  
  326.     /* replacements for the standard functions */
  327.     int spawnv(int type, const char *name, const char **args) ;
  328.     int spawnvp(int type, const char *name, const char **args) ;
  329.     int spawnve(int type, const char *name, const char **args,
  330.             const char **env) ;
  331.     int spawnvpe(int type, const char *name, const char **args,
  332.              const char **env) ;
  333.     int spawnl(int type, const char *name, const char *argv0, ...) ;
  334.     int spawnlp(int type, const char *name, const char *argv0, ...) ;
  335.     int spawnle(int type, const char *name, const char *argv0, ...) ;
  336.     int spawnlpe(int type, const char *name, const char *argv0, ...) ;
  337.     int system(const char *command) ;
  338.     /* Note: the above functions return -1 (error) if 'type' is not */
  339.     /*     P_WAIT     */
  340.  
  341.     /* setup function */
  342.     void init_SPAWNO(const char *overlay_path, int swap_types) ;
  343.     /* setup swapping options for the compatibility functions above */
  344.  
  345.     /* SPAWNO-specific functions */
  346.     int spawnvo(const char *overlay_path, const char *name,
  347.             const char **args) ;
  348.     int spawnvpo(const char *overlay_path, const char *name,
  349.              const char **args) ;
  350.     int spawnveo(const char *overlay_path, const char *name,
  351.              const char **args,const char **env) ;
  352.     int spawnvpeo(const char *overlay_path, const char *name,
  353.              const char **args,const char **env) ;
  354.     int spawnlo(const char *overlay_path, const char *name, ...) ;
  355.     int spawnlpo(const char *overlay_path, const char *name, ...) ;
  356.     int spawnleo(const char *overlay_path, const char *name, ...) ;
  357.     int spawnlpeo(const char *overlay_path, const char *name, ...) ;
  358.     int systemo(const char *overlay_path, const char *command) ;
  359.     /* Note: the ..o() functions use the current directory only if */
  360.     /*     overlay_path is NULL; the only function which checks  */
  361.     /*     the environment variables SWAPDIR and TEMP is           */
  362.     /*     init_SPAWNO().                        */
  363.  
  364. Global variables:
  365.        char __spawn_xms ;
  366.         Specify whether to use XMS memory for swapping (if available).
  367.         0 = no, 1 = yes, default = 1
  368.         This variable is set by init_SPAWNO().
  369.        char __spawn_ems ;
  370.         Specify whether to use EMS memory for swapping (if available).
  371.         0 = no, 1 = yes, default = 1
  372.         This variable is set by init_SPAWNO().
  373.        char __spawn_ext ;  /* 0 = don't use non-XMS extended memory for swap */
  374.         Specify whether to use non-XMS extended memory (via INT 15h) for
  375.         swapping (if available).  0 = no, 1 = yes, default = 1
  376.         This variable is set by init_SPAWNO().
  377.         Note: SPAWNO should not be allowed to swap to extended memory if
  378.         running under a multitasker or task switcher, as other programs
  379.         would be able to grab the same memory used by SPAWNO to store the
  380.         swapped-out program.  For this reason, SPAWNO automatically
  381.         disables swapping to non-XMS extended memory if it detects that
  382.         TopView, DESQview, or any other TopView API-compatible multi-
  383.         tasker is active, or the DOS 5 task switcher is loaded, or
  384.         MS Windows 3 is running in real or standard mode (enhanced mode
  385.         is not readily detectable from a program, unfortunately).
  386.        const char *pascal ___spawn_swap_dirs ;
  387.         Specify the list of directories in which to attempt to store
  388.         the swap file when swapping to disk.  The directories are
  389.         separated by semicolons just as they would be in the PATH
  390.         environment variable.  Default = "." (current directory)
  391.         This variable is set by init_SPAWNO().
  392.         Note: SPAWNO will not swap to disk if this variable is set to an
  393.         empty string; if it is set to NULL, SPAWNO will use the default
  394.         of ".".
  395.        char __spawn_keepints ;
  396.         Specify whether to deactivate INT 23h and INT 24h handlers by
  397.         temporarily restoring the vectors stored in the PSP.
  398.         0 = no, nonzero = yes, default = 0
  399.        char __spawn_swap_UMA ;
  400.         Specify whether to swap out memory blocks in the upper memory
  401.         area (640K-1M).  0 = no, 1 = yes, default = 1
  402.         Note: This option only has an effect under MSDOS 5.0 with the
  403.         line DOS=UMB or DOS=HIGH,UMB in CONFIG.SYS.
  404.        unsigned __spawn_resident ;
  405.         Specify the minimum number of paragraphs in the memory block
  406.         containing the PSP to keep resident while in the child program.
  407.         This value will be increased if necessary to be large enough to
  408.         hold the swapping code; it may also be increased slightly if it
  409.         causes the end of the shrunken PSP block to fall within a
  410.         specific section of SPAWNO's code.  You may force the entire
  411.         main block to stay in memory by setting this variable to 0xFFFF;
  412.         however, the environment and any additional memory blocks
  413.         allocated by the program will still be swapped out.  default = 0
  414.         Note: in addition to the PSP memory block, a small second block
  415.         is used for the stack needed by the swapping code (see below).
  416.        unsigned __spawn_res_stack ;
  417.         Specify the minimum number of paragraphs of the stack to keep
  418.         resident while in the child program.  Default = 4, minimum = 2
  419.         (two paragraphs is only sufficient for bare DOS; TSRs which
  420.         hook INT 21h will increase the stack requirements, but four is
  421.         sufficient for most systems).  SPAWNO attempts to compute the
  422.         necessary stack size, but this variable allows the computed
  423.         value to be overridden if necessary.
  424.  
  425. External functions called by SPAWNO:
  426.     malloc()   \ only when passing an array of environment strings
  427.     free()       /
  428.  
  429. External variables referenced by SPAWNO:
  430.     int errno ;
  431.     int _doserrno ;
  432.     unsigned int _psp ;
  433.     char **environ ;  (only when passing an array of environment strings)
  434.  
  435. Other:
  436.     This version of SPAWNO overwrites the PSP, so the commandline
  437.     will be lost unless it was copied before the first spawn().
  438.  
  439.  
  440. -----------------
  441. Functions (Turbo Pascal):
  442.     init_SPAWNO(swap_dirs : string ; swap_types : integer ;
  443.             min_resident : integer ; resident_stack : integer) ;
  444.     spawn(program_name : string ; arguments : string ;
  445.           envseg : integer) : integer ;
  446.  
  447. Global Variables (Turbo Pascal):
  448.     spawno_error : integer ;   (error code when spawn() returns -1)
  449.  
  450.  
  451. -----------------
  452. Send comments, bug reports, etc. to
  453.  
  454.      Internet: ralf+@cs.cmu.edu
  455.      Fidonet:  Ralf Brown 1:129/26.1 (or post a message to me on DR_DEBUG--I
  456.                      have to route netmail outside Zone 1
  457.                      via Internet -> Fidonet gateways, which
  458.                      is not always reliable)
  459. or
  460.      Ralf Brown
  461.      Suite #26
  462.      813 Copeland Way
  463.      Pittsburgh, PA 15232
  464.